import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** 
* @author 朱宏亮
* @version 创建时间：2017年12月5日 下午12:30:08 
* 类说明 
* 未整合spring
* 消费者订阅模式
*/
public class ConsumerTopic {

    private static final Logger log = LoggerFactory.getLogger(ConsumerTopic.class);

      //连接账号
      private static final  String userName = "admin";
      //连接密码
      private static final String password = "admin";
      //连接地址
      private String brokerURL = "tcp://localhost:61616";
      //connection的工厂
      private ConnectionFactory factory;
      //连接对象
      private Connection connection;
      //一个操作会话
      private Session session;
      //目的地，其实就是连接到哪个队列，如果是点对点，那么它的实现是Queue，如果是订阅模式，那它的实现是Topic
      private Destination destination;
      //消费者，就是接收数据的对象
      private MessageConsumer consumer;
      private MessageConsumer consumer2;
      public static void main(String[] args) {
          ConsumerTopic cl = new ConsumerTopic();
          cl.getMsg();
      }
      
      public void getMsg(){
          try {
              //根据用户名，密码，url创建一个连接工厂
              factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
              //从工厂中获取一个连接
              connection = factory.createConnection();
              connection.setClientID("ClientID连接1"); // 为Connection指定ClientID
              connection.start();
              //创建一个session
              //第一个参数:是否支持事务，如果为true，则会忽略第二个参数，被jms服务器设置为SESSION_TRANSACTED
              //第二个参数为false时，paramB的值可为Session.AUTO_ACKNOWLEDGE，Session.CLIENT_ACKNOWLEDGE，DUPS_OK_ACKNOWLEDGE其中一个。
              //Session.AUTO_ACKNOWLEDGE为自动确认，客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常，也会被当作正常发送成功。
              //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后，必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功，并删除消息。
              //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回，会话对象就会确认消息的接收；而且允许重复确认。
              session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             
              /**
               * 使用这2行代码创建的consumer不能接收到持久化消息
               * 
               * 创建一个到达的目的地
               * destination = session.createTopic("topic");// ---------与点对点不同之处
               * 根据session，创建一个接收者对象
               * consumer = session.createConsumer(destination);
               */
              
              /**
               * 要实现接受持久化消息必须为subscriber指定name
               */
              //第一个消费者
              consumer = session.createDurableSubscriber(session.createTopic("topic朱宏亮"), "消费者一号"); // 为subscriber指定name
              //实现一个消息的监听器
              //实现这个监听器后，以后只要有消息，就会通过这个监听器接收到
              consumer.setMessageListener(new MessageListener() {
                  @Override
                  public void onMessage(Message message) {
                      try {
                          //获取到接收的数据
                          String text = ((TextMessage)message).getText();
                          log.info("消费者一号消息接收成功:{}",text);
                      } catch (JMSException e) {
                          log.error("消费者一号消息接收失败:{}",e.getMessage());
                      }
                  }
              });
              
              //第二个消费者
              consumer2 = session.createDurableSubscriber(session.createTopic("topic朱宏亮"), "消费者二号"); 
              consumer2.setMessageListener(new MessageListener() {
                  @Override
                  public void onMessage(Message message) {
                      try {
                          //获取到接收的数据
                          String text = ((TextMessage)message).getText();
                          log.info("消费者二号消息接收成功:{}",text);
                      } catch (JMSException e) {
                          log.error("消费者二号消息接收失败:{}",e.getMessage());
                      }
                  }
              });
              

          //消费方不要关闭，让它一直开着。
          } catch (JMSException e) {
              log.error("method getMsg,error msg:{}",e.getMessage());
          }
      }
}
 